package org.yzh.commons.auth;

import com.auth0.jwt.exceptions.TokenExpiredException;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import org.springframework.web.method.HandlerMethod;
import org.springframework.web.servlet.HandlerInterceptor;
import org.springframework.web.servlet.ModelAndView;
import org.yzh.commons.annotations.RequiresRoles;
import org.yzh.commons.model.UserPrincipal;
import org.yzh.commons.model.enums.Role;
import org.yzh.commons.util.JWTUtil;

import java.io.IOException;

public class AuthorizationInterceptor implements HandlerInterceptor {

    public final static String HeaderName = "Authentication";

    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws IOException {
        String token = request.getHeader(HeaderName);
        if (token == null)
            token = request.getParameter(HeaderName);

        if (token != null) {
            UserPrincipal user;
            try {
                user = JWTUtil.unsign(token);
            } catch (TokenExpiredException e) {
                response.setStatus(401);
                response.getWriter().println("令牌过期");
                return false;
            } catch (Exception e) {
                response.setStatus(401);
                response.getWriter().println("令牌格式错误");
                return false;
            }
            request.setAttribute("user", user);

            RequiresRoles requiresRoles = ((HandlerMethod) handler).getMethodAnnotation(RequiresRoles.class);
            if (requiresRoles == null)
                return true;

            Role role = user.getRole();
            Role[] roles = requiresRoles.value();
            for (Role t : roles)
                if (role == t)
                    return true;
        }

        response.setStatus(403);
        response.getWriter().println("用户认证失败");
        return false;
    }

    public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) {
    }

    public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) {
    }
}